#include "CEntranceHttpServer.h"
#include "CControlManage.h"
#include "cmdHandle/CNetConfig.h"
#include "include/CConfig.h"
#include "cmdHandle/CWebUserInfo.h"
NETWORKSERVICE_BEGIN_NAMESPACE

#define CMD_ROOT "/cmd/*"
#define CMD_ROOT_2 "/api/cmd/*"
#define LOGIN_ROOT "/login"
#define UPLOAD_ROOT "/upload"
#define WEB_FILE_ROOT "/file/#"


bool httpDataHander(struct mg_connection *c,struct mg_http_message *hm, void *fn_data)
{
	CEntranceHttpServer *pThis = (CEntranceHttpServer *)fn_data;
	if(pThis)
		return pThis->__dataHandle(c, hm);
	return true;
}

bool loginHander(struct mg_connection *c,struct mg_http_message *hm, void *fn_data)
{
	CEntranceHttpServer *pThis = (CEntranceHttpServer *)fn_data;
	if(pThis)
		return pThis->__loginHander(c, hm);
	return true;
}

bool dirHander(struct mg_connection *c,struct mg_http_message *hm, void *fn_data)
{
	CEntranceHttpServer *pThis = (CEntranceHttpServer *)fn_data;
	if(pThis)
		pThis->__dirHander(c, hm);
	return true;
}

// 构造函数
CEntranceHttpServer::CEntranceHttpServer()
:m_HttpServer("")
{

}

// 析构函数
CEntranceHttpServer::~CEntranceHttpServer()
{

}

// 启动客服端
void CEntranceHttpServer::startServer(string url)
{
	m_HttpServer.registerHandler(CMD_ROOT, httpDataHander, this);
	m_HttpServer.registerHandler(CMD_ROOT_2, httpDataHander, this);
	m_HttpServer.registerHandler(LOGIN_ROOT, loginHander, this);
	m_HttpServer.registerHandler(WEB_FILE_ROOT, dirHander, this);
	m_HttpServer.setuploadFileHandler(UPLOAD_ROOT,SP_WEB_UPLOAD_FILE_PATH, STD_BIND_FUNC(CEntranceHttpServer::__uploadHander, this, _1, _2));
	m_HttpServer.registerWebHandler(STD_BIND_FUNC(CEntranceHttpServer::__wegHandle, this, _1, _2));
	m_HttpServer.start(url);

}

// 停止客服端
void CEntranceHttpServer::stopServer()
{
	m_HttpServer.stop();
}

// 添加监听命令
void CEntranceHttpServer::addCmd(string cmd)
{
	m_HttpServer.registerHandler(cmd, httpDataHander, this);
}

// 发送数据
bool CEntranceHttpServer::sendData(unsigned long onlyId, MAP_PARAMS &head, string &bodyData)
{
	return m_HttpServer.sendData(onlyId, head, bodyData);
}

// 发送数据
bool CEntranceHttpServer::sendData(unsigned long onlyId,string &heads, string &bodyData)
{
	return m_HttpServer.sendData(onlyId, heads, bodyData);
}

// 发送数据
bool CEntranceHttpServer::sendData(unsigned long onlyId,struct mg_http_serve_opts sopts, struct mg_http_message *hm)
{
	return m_HttpServer.sendData(onlyId, sopts, hm);
}

// 数据处理
bool CEntranceHttpServer::__dataHandle(struct mg_connection *c, struct mg_http_message *hm)
{
	string msg = string(hm->message.ptr, hm->message.len);
    qDebug("%s", msg.c_str());
	struct _tCmdBaseData head;
	// 获取命令
	string url(hm->uri.ptr,(int)hm->uri.len);
	if(url.find(string(CMD_ROOT_2, strlen(CMD_ROOT_2)-1)) != url.npos){
		head.cmd = (int)hm->uri.len > (int)strlen(CMD_ROOT_2)-1 ? url.substr(strlen(CMD_ROOT_2)-1):"";
	} else {
		head.cmd = (int)hm->uri.len > (int)strlen(CMD_ROOT)-1 ? url.substr(strlen(CMD_ROOT)-1):"";
	}

	for(int i  = 0; i < MG_MAX_HTTP_HEADERS; i++){
		int KeyLen = (int)hm->headers[i].name.len;
		int valueLen = (int)hm->headers[i].value.len;
		if(KeyLen > 0 && valueLen > 0){
			string key = string(hm->headers[i].name.ptr,KeyLen);
			string value = string(hm->headers[i].value.ptr,valueLen);
			if(key == "sn"){
				head.sn = value;
			} else if(key == "timestamp"){
				head.timestamp = atol(value.c_str());
			} else if(key == "sendMsgId"){
				head.sendMsgId = value;
			} else if(key == "appKey"){
				head.appKey = value;
			} else if(key == "signature"){
				head.signature = value;
			}
		}
	}


	// 判断鉴权key
	if(head.sendMsgId.empty()){
		struct tCmdData<string> retData;
        retData.code = 302;
        retData.data = "";
		if(head.sendMsgId.empty()){
            retData.msg = "sendMsgId为空";
		}
		string retBody;
		MAP_PARAMS retHead;
		retHead["Content-Type"] = "application/json;charset=utf-8";
        retData.toJsonString(retBody);
		return m_HttpServer.sendData(c->id, retHead, retBody);
	}
    string body = (int)hm->body.len > 0 ? string(hm->body.ptr, (int)hm->body.len): "{}";
	const T_NetConfig& netConfig = CNetConfig::getConfig();
    string md5str = controlManage::strMd5(controlManage::strMd5(head.sendMsgId + to_string(head.timestamp)));
    qDebug("md5str:%s", md5str.c_str());
    qDebug("head.strSignature:%s", head.signature.c_str());

	struct tRoute route;
    route.isAuthorizationSuccess = (head.signature == md5str);
	route.type = ROUTE_HTTP_CLIENT;
	route.httpId = c->id;


    return controlManage::runHttpHandle(&head, body, &route);
}



// 登录处理
bool CEntranceHttpServer::__loginHander(struct mg_connection *c, struct mg_http_message *hm)
{
	string msg = string(hm->message.ptr, hm->message.len);
    qDebug("%s", msg.c_str());

	string retBody;
	MAP_PARAMS retHead;
	retHead["Content-Type"] = "application/json;charset=utf-8";

	T_UserInfo msgLogin;
	msgLogin.loadJsonString(hm->body.ptr);
	T_UserInfo &localLogin = CWebUserInfo::getUserInfo();
    qDebug("%s", msgLogin.toJsonString().c_str());
    qDebug("%s", localLogin.toJsonString().c_str());
	if(localLogin.username != msgLogin.username || localLogin.password != msgLogin.password){
		struct tCmdData<string> retData;
        retData.code = NET_CODE_SIGNATURE_FIAL;
        retData.msg  = "账号密码错误";
		retData.toJsonString(retBody);
		m_HttpServer.sendData(c->id, retHead, retBody);
		return false;

	}

	struct tCmdData<T_NetConfig> retData;
    retData.data = CNetConfig::getConfig();
    retData.toJsonString(retBody);
    qDebug("%s", retBody.c_str());
	m_HttpServer.sendData(c->id, retHead, retBody);
	return false;
}

// 文件上传处理
void CEntranceHttpServer::__uploadHander(struct mg_connection *c, string savePath)
{
	struct tCmdData<string> retData;
    retData.data = savePath;
	string retBody;
	MAP_PARAMS retHead;
	retHead["Content-Type"] = "application/json;charset=utf-8";
    retData.toJsonString(retBody);
    qDebug("%s",retBody.c_str());
	m_HttpServer.sendData(c->id, retHead, retBody);
}

// web访问文件处理
void CEntranceHttpServer::__dirHander(struct mg_connection *c, struct mg_http_message *hm)
{
    struct mg_http_serve_opts opts = {0};
    opts.root_dir = "/";

    if(hm->uri.len > strlen("/file")){
		hm->uri.ptr += strlen("/file");
		hm->uri.len -= strlen("/file");
    }
    mg_http_serve_dir(c, hm, &opts);
}

// web处理
void CEntranceHttpServer::__wegHandle(struct mg_connection *c, struct mg_http_message *hm)
{
    struct mg_http_serve_opts opts = {0};
    opts.root_dir = "./web_root/";
    mg_http_serve_dir(c, hm, &opts);
}

NETWORKSERVICE_END_NAMESPACE
